
#include "CAnimatedBillboardSceneNode.h"

// -------------------------------------------------------------------------------
// Animated billboard Scene Node factory implementation
// -------------------------------------------------------------------------------

// type name for our scene node
const char* animatedBillboardSceneNodeTypeName = "animatedbillboard";

CAnimatedBillboardSceneNodeFactory::CAnimatedBillboardSceneNodeFactory(ISceneManager* mgr)
: Manager(mgr)
{
}

CAnimatedBillboardSceneNodeFactory::~CAnimatedBillboardSceneNodeFactory()
{
}

//! adds a scene node to the scene graph based on its type id
ISceneNode* CAnimatedBillboardSceneNodeFactory::addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent)
{
	if (!parent)
		parent = Manager->getRootSceneNode();

	if (type == CAnimatedBillboardSceneNode::ANIMATED_BILLBOARD_SCENE_NODE_ID)
	{
		CAnimatedBillboardSceneNode* node = new CAnimatedBillboardSceneNode(-1, core::vector3df(0, 0, 0));
		parent->addChild(node);
		node->drop();
		return node; 
	}

	return 0;
}


//! adds a scene node to the scene graph based on its type name
ISceneNode* CAnimatedBillboardSceneNodeFactory::addSceneNode(const c8* typeName, ISceneNode* parent)
{
	return addSceneNode( getTypeFromName(typeName), parent );
}


//! returns amount of scene node types this factory is able to create
u32 CAnimatedBillboardSceneNodeFactory::getCreatableSceneNodeTypeCount() const
{
	return 1;
}


//! returns type of a createable scene node type
ESCENE_NODE_TYPE CAnimatedBillboardSceneNodeFactory::getCreateableSceneNodeType(u32 idx) const
{
	if (idx==0)
		return (ESCENE_NODE_TYPE)CAnimatedBillboardSceneNode::ANIMATED_BILLBOARD_SCENE_NODE_ID;

	return ESNT_UNKNOWN;
}


//! returns type name of a createable scene node type 
const c8* CAnimatedBillboardSceneNodeFactory::getCreateableSceneNodeTypeName(u32 idx) const
{
	if (idx==0)
		return animatedBillboardSceneNodeTypeName;

	return 0;
}


//! returns type name of a createable scene node type 
const c8* CAnimatedBillboardSceneNodeFactory::getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const
{
	if (type == CAnimatedBillboardSceneNode::ANIMATED_BILLBOARD_SCENE_NODE_ID)
		return animatedBillboardSceneNodeTypeName;

	return 0;
}


ESCENE_NODE_TYPE CAnimatedBillboardSceneNodeFactory::getTypeFromName(const c8* name)
{
	if (!strcmp(name, animatedBillboardSceneNodeTypeName))
		return (ESCENE_NODE_TYPE)CAnimatedBillboardSceneNode::ANIMATED_BILLBOARD_SCENE_NODE_ID;

	return ESNT_UNKNOWN;
}



// -------------------------------------------------------------------------------
// Animated billboard Scene Node implementation
// -------------------------------------------------------------------------------

//! constructor
CAnimatedBillboardSceneNode::CAnimatedBillboardSceneNode( s32 id,
			const core::vector3df& position)
	: ISceneNode( id, position)
{
	m_sprite = 0;
	m_spriteInstance = 0;
}

CAnimatedBillboardSceneNode::~CAnimatedBillboardSceneNode()
{
	if(m_sprite)
	{
		delete m_sprite;
		m_sprite = NULL;
	}

	if(m_spriteInstance)
	{
		delete m_spriteInstance;
		m_spriteInstance = NULL;
	}
}

//! pre render event
void CAnimatedBillboardSceneNode::OnRegisterSceneNode()
{
	if (IsVisible)
		SceneManager->registerNodeForRendering(this);

	ISceneNode::OnRegisterSceneNode();
}


//! render
void CAnimatedBillboardSceneNode::render()
{
	if(m_spriteInstance)
	{
		m_spriteInstance->Draw3D(getPosition());
		m_spriteInstance->Update();
	}
}


//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CAnimatedBillboardSceneNode::getBoundingBox() const
{
	return BBox;
}

//! sets the size of the billboard
void CAnimatedBillboardSceneNode::setSize(const core::dimension2d<f32>& size)
{
	Size = size;

	if (Size.Width == 0.0f)
		Size.Width = 1.0f;

	if (Size.Height == 0.0f )
		Size.Height = 1.0f;

	f32 avg = (size.Width + size.Height)/6;
	BBox.MinEdge.set(-avg,-avg,-avg);
	BBox.MaxEdge.set(avg,avg,avg);
}

//! gets the size of the billboard
const core::dimension2d<f32>& CAnimatedBillboardSceneNode::getSize() const
{
	return Size;
}

//! sets the sprite instance to render
void CAnimatedBillboardSceneNode::LoadSprite(const char* spriteName)
{
	if(m_sprite)
	{
		delete m_sprite;
		m_sprite = NULL;
	}
	if(m_spriteInstance)
	{
		delete m_spriteInstance;
		m_spriteInstance = NULL;
	}

	if(spriteName && strcmp(spriteName, "") != 0)
	{
		m_sprite = new ASprite();
		m_sprite->LoadSprite(spriteName);
		m_spriteInstance = new ASpriteInstance();
		m_spriteInstance->SetASprite(m_sprite);
	}
}

//! sets the sprite instance to render
void CAnimatedBillboardSceneNode::LoadTexture(const char* textureName)
{
	if(m_sprite)
		m_sprite->LoadTexture(textureName);	
}

//! Writes attributes of the scene node.
void CAnimatedBillboardSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
	ISceneNode::serializeAttributes(out, options);
}


//! Reads attributes of the scene node.
void CAnimatedBillboardSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	ISceneNode::deserializeAttributes(in, options);
}

